package cn.itcast.nems.manager.ems;

import cn.itcast.nems.manager.util.Md5Util;
import cn.itcast.nems.manager.util.OkHttpUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Map;
import java.util.TreeMap;

@Setter
@Getter
@AllArgsConstructor
public class EmsManger {
    private final static Logger logger = LoggerFactory.getLogger(EmsManger.class);
    private String emsDomain;
    private String emsSignature;
    private String emsCid;

    public String doPost(String json, String loginUser, String apiPath, String method) throws Exception {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", method);
        params.put("params", json);
        var emsUrl = emsDomain + apiPath;
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[确认报名] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }

    /**
     * 批量学籍流转
     *
     * @param requestBodyJson 学籍流转数据
     * @return EMS返回结果
     */
    public String batchClassCirculation(String requestBodyJson) {
        TreeMap<String, Object> params = new TreeMap<>();
        String ts = String.valueOf(System.currentTimeMillis());
        params.put("ts", ts);
        params.put("cid", emsCid);
        params.put("method", "batchClassCirculation");
        String emsUrl = emsDomain + "/student.do";
        String sig = Md5Util.calSignature(params, emsSignature);
        emsUrl += "?cid=" + emsCid + "&ts=" + ts + "&method=batchClassCirculation&sig=" + sig;
        logger.info("[同步老EMS] 调用EMS接口: {}", emsUrl);
        return OkHttpUtil.doPost(emsUrl, requestBodyJson);
    }

    /**
     * 休学
     *
     * @param oldEmsSjcId   老EMS学籍ID
     * @param suspendDate   休学日期
     * @param operatorEmail 当前操作email
     * @return EMS返回结果
     * @throws Exception
     */
    public String suspension(Integer oldEmsSjcId, LocalDate suspendDate, String operatorEmail) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("studentJoinClazzId", oldEmsSjcId);
        params.put("suspendDate", suspendDate.toString());
        return this.doPost(params, operatorEmail, "/student.do", "suspend");
    }

    /**
     * 合并学员
     *
     * @param fromStudentId 被合并的学员
     * @param toStudentId   合并后保留下来的学员
     * @param type          合并原因
     * @param operatorEmail 操作者ID
     * @return 同步老EMS结果
     */
    public String mergeStudent(Integer fromStudentId, Integer toStudentId, String type, String operatorEmail) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("fromStudentId", fromStudentId);
        params.put("toStudentId", toStudentId);
        params.put("type", type);
        return this.doPost(params, operatorEmail, "/student.do", "mergeStudent");
    }

    /**
     * 退费
     *
     * @param map 退费数据
     * @return EMS返回结果
     * @throws Exception 当出现异常或EMS接口返回错误时抛出异常
     */
    public String refund(Map<String, Object> map, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", "refund");
        params.putAll(map);
        String emsUrl = emsDomain + "/student/journal.do";
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[同步老EMS] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }

    /**
     * 退学
     *
     * @param map 退费数据
     * @return EMS返回结果
     */
    public String dropout(TreeMap<String, Object> map, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", "leaveSchool");
        params.putAll(map);
        String emsUrl = emsDomain + "/student.do";
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[同步老EMS] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }

    /**
     * 费用转移
     *
     * @param map 退费数据
     * @return EMS返回结果
     * @throws Exception 当出现异常或EMS接口返回错误时抛出异常
     */
    public String fundTransfer(TreeMap<String, Object> map, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", "movefee");
        params.putAll(map);
        String emsUrl = emsDomain + "/student/journal.do";
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[同步老EMS] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }
    /**
     * 补录流水
     *
     * @param map 退费数据
     * @return EMS返回结果
     * @throws RuntimeException 当出现异常或EMS接口返回错误时抛出异常
     */
    public String fundFlow(TreeMap<String, Object> map, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", "payment");
        params.putAll(map);
        String emsUrl = emsDomain + "/student/journal.do";
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[同步老EMS] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }

    public String suspensionReturn(Integer sjcId, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", "suspendReturn");
        params.put("sjcId", String.valueOf(sjcId));
        String emsUrl = emsDomain + "/student.do";
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("[同步老EMS] 调用EMS接口: {}, 请求参数: {}", emsUrl, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
        // method =
    }

    /**
     * 调整老EMS学籍应交价格
     *
     * @param oldEmsSjcId 老EMS学籍ID
     * @param price       调整金额
     * @param loginUser   登陆人邮箱
     * @return java.lang.String
     * @author 高昌露
     * @since 2024/3/19 10:52
     */
    public String adjustPrice(Integer oldEmsSjcId, BigDecimal price, String loginUser) {
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("sjcId", oldEmsSjcId);
        params.put("price", price);
        return this.doPost(params, loginUser, "/student.do", "adjustPrice");
    }

    /**
     * 请求老EMS通用方法
     *
     * @param params    业务请求参数
     * @param loginUser 当前登陆人邮箱
     * @param apiPath   请求接口
     * @param method    请求方法, 配合apiPath定位到具体需要路由到老EMS哪个接口
     * @return java.lang.String
     * @author 高昌露
     * @since 2024/3/19 10:45
     */
    private String doPost(@NonNull TreeMap<String, Object> params, String loginUser, @NonNull String apiPath, @NonNull String method) {
        params.put("ts", String.valueOf(System.currentTimeMillis()));
        params.put("cid", emsCid);
        params.put("method", method);
        var emsUrl = emsDomain + apiPath;
        Md5Util.handlerSignature(params, emsSignature);
        logger.info("调用EMS接口: {}, 请求方法:{}, 请求参数: {}", emsUrl, method, params);
        return OkHttpUtil.doPost(emsUrl, params, loginUser);
    }
}
